import shuffle from 'lodash-es/shuffle'
import { HOT_RACE_ARR } from '@/constant'
import { hashMD5 } from './cryptojs'
import { hasFrom } from './qs'

export const stringifyUrl = obj => {
  return Object.keys(obj)
    .reduce((target, key) => {
      if (obj[key] === 0 || obj[key]) {
        target += `${key}=${obj[key]}&`
      }
      return target
    }, '?')
    .slice(0, -1)
}

export const isPureNumber = str => /^[1-9]\d*$/.test(str)
// 六位数字校验
export const isSexPureNumber = str => /^[0-9]{6}$/.test(str)
// 生成粗略的随机字符串
export const generateRandomString = (length = 10) => {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
  let result = ''
  for (let i = 0; i < length; i++) {
    const randomIndex = Math.floor(Math.random() * chars.length)
    result += chars[randomIndex]
  }
  return result
}

// 滚动到顶部
export const scrollToTop = () => {
  window.scrollTo({
    top: 0,
    behavior: 'smooth'
  })
}

const isPcDevice = () => {
  const userAgentInfo = navigator.userAgent
  const Agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod']
  let flag = true
  for (let i = 0; i < Agents.length; i++) {
    if (userAgentInfo.indexOf(Agents[i]) > 0) {
      flag = false
      break
    }
  }
  return flag
}

/**
 * 网页设备平台
 * */
export const devicePlatform = () => {
  const isAndroid = /(android)/i.test(navigator.userAgent)
  const isIOS = /(iphone|ipad|ipod)/i.test(navigator.userAgent)
  const isPC = isPcDevice()
  return {
    isAndroid,
    isIOS,
    isPC
  }
}

/**
 * 视口触底判断
 * */
export const isElementInViewport = el => {
  try {
    const rect = el.getBoundingClientRect()
    return rect.top >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight)
  } catch (error) {
    return false
  }
}

export const removeDuplicates = (arr, key = 'id') => {
  const result = []
  arr.forEach(obj => {
    if (!result.some(item => item[key] === obj[key])) {
      result.push(obj)
    }
  })
  return result
}
/**
 * 未登录缓存历史记录
 * */

export const cacheHistory = (type = 'VOD', target) => {
  if (type === 'VOD') {
    let vodHistory = JSON.parse(localStorage.getItem('vod-history') || '[]')
    vodHistory.unshift(target)
    vodHistory = removeDuplicates(vodHistory, 'eid')
    localStorage.setItem('vod-history', JSON.stringify(vodHistory))
  } else {
    let liveHistory = JSON.parse(localStorage.getItem('live-history') || '[]')
    liveHistory.unshift(target)
    liveHistory = removeDuplicates(liveHistory)
    if (liveHistory.length > 6) {
      liveHistory.length = 6
    }
    localStorage.setItem('live-history', JSON.stringify(liveHistory))
  }
}

/**
 * 分出相关的观看历史
 * */
const diff7days = 7 * 86400
export const dividerHistory = arr => {
  const now = parseInt(new Date().valueOf() / 1000)
  const latest = arr.filter(item => {
    const diff = now - item.playTime
    return diff <= diff7days
  })
  const previous = arr.filter(item => {
    const diff = now - item.playTime
    return diff > diff7days
  })

  return [latest, previous]
}

/**
 * 动态注入脚本，节流控制
 * */
export const injectScript = (src, key) => {
  return new Promise(resolve => {
    const scripts = document.getElementsByTagName('script')
    for (let i = 0; i < scripts.length; i++) {
      if (scripts[i].getAttribute('unique-key') === key) {
        resolve()
        return
      }
    }
    const scriptTag = document.createElement('script')
    scriptTag.src = src
    scriptTag.setAttribute('unique-key', key)
    document.getElementsByTagName('head')[0].appendChild(scriptTag)
    scriptTag.addEventListener('load', resolve)
    scriptTag.addEventListener('error', resolve)
  })
}

/**
 * 二分查找正序数组符合的数据
 * @param arr 查找数组
 * @param target 查找对象
 * @param type 查找类型:positive:正序,reverse:逆序
 * */
export const binarySearch = (arr, target, type = 'positive', low = 0, high = arr.length - 1) => {
  if (low > high) {
    return -1
  }

  const mid = Math.floor((low + high) / 2)
  const guess = arr[mid]

  if (guess === target) {
    return mid
  } else if (guess < target) {
    const params = type === 'positive' ? [mid + 1, high] : [low, mid - 1]
    return binarySearch(arr, target, type, ...params)
  } else {
    const params = type === 'positive' ? [low, mid - 1] : [mid + 1, high]
    return binarySearch(arr, target, type, ...params)
  }
}

// 获取随机8个数
export const getShuffleHots = () => {
  return shuffle(HOT_RACE_ARR).slice(0, 8)
}

// 体育赛程生成映射对象
export const generateMapRace = (project, urlMap) => {
  return project.map(item => {
    const itemChild = urlMap.filter(child => child.projectId == item.id)
    item.children = itemChild
    return item
  })
}

// 获取数组中最接近某个目标数字的数字
export const findClosestNumber = (arr, target) => {
  let start = 0
  let end = arr.length - 1

  while (start <= end) {
    const mid = Math.floor((start + end) / 2)

    if (arr[mid] === target) {
      return arr[mid]
    } else if (arr[mid] > target) {
      end = mid - 1
    } else {
      start = mid + 1
    }
  }
  if (end < 0) {
    return arr[start]
  } else if (start >= arr.length) {
    return arr[end]
  } else {
    return Math.abs(target - arr[start]) < Math.abs(target - arr[end]) ? arr[start] : arr[end]
  }
}

// 组装生成直播url
export const generatePlayUrl = (liveUrl, auth_key) => {
  const token = localStorage.getItem('token')
  const urlArr = liveUrl.split('?')
  const url = urlArr[0].replace('http://', 'https://')
  const stream_id = url.split('/').pop().split('.')[0]
  const timestamp = Math.floor(new Date().getTime() / 1000)
  const rand = generateRandomString() || 'vY0JVDdLhu'
  const uuid = generateRandomString() || 'pbHYqiL3uy'
  const jismiStr = '' + auth_key + timestamp + rand + uuid + stream_id + token
  const sign = hashMD5(jismiStr)
  const params = {
    stream_id,
    timestamp,
    rand,
    uuid,
    from: 'web',
    sign,
    token
  }
  if (!hasFrom(liveUrl)) {
    params.from = 'web'
  }
  let finalUrl = url + stringifyUrl(params)
  if (urlArr.length > 1) {
    try {
      urlArr[1] = urlArr[1]?.split('&token')[0]
    } catch (error) {}
    finalUrl += '&' + urlArr[1]
  }
  return finalUrl
}
// 组装生成点播url
export const generateVodUrl = (url, auth_key) => {
  if (!url) {
    return 'error'
  }
  let finalUrl = url.replace('http://', 'https://')
  const token = localStorage.getItem('token')
  const timestamp = Math.floor(new Date().getTime() / 1000)
  const rand = generateRandomString() || 'vY0JVDdLhu'
  const uuid = generateRandomString() || 'pbHYqiL3uy'
  const jismiStr = '' + auth_key + timestamp + rand + uuid + token
  const sign = hashMD5(jismiStr)
  const params = {
    timestamp,
    rand,
    uuid,
    from: 'web',
    sign,
    token
  }
  if (!hasFrom(url)) {
    params.from = 'web'
  }
  return finalUrl + stringifyUrl(params)
}

export const isJSONString = str => {
  try {
    JSON.parse(str)
    return true
  } catch (error) {
    return false
  }
}

export const goBack = () => {
  if (!sessionStorage.getItem('lastPage')) {
    localStorage.setItem('lastPage', true)
    window.location.href = '/'
    return
  }
  try {
    window.history.back()
  } catch (error) {}
}

export const openNewTab = url => {
  const aTag = document.createElement('a')
  aTag.setAttribute('href', url)
  aTag.setAttribute('target', '_blank')
  document.body.appendChild(aTag)
  aTag.click()
  document.body.removeChild(aTag)
}

export const preventScroll = (el, type) => {
  if (type === 'in') {
    el.classList.add('stop-scrolling')
  } else {
    el.classList.remove('stop-scrolling')
  }
}

String.prototype.toFix = function (num) {
  if (!this || isNaN(this)) {
    return this
  }
  return (+this).toFixed(num)
}

// 往页面中注入结构化数据
export const injectStructData = (data, key) => {
  const scriptTag = document.createElement('script')
  scriptTag.type = 'application/ld+json'
  scriptTag.setAttribute('unique-key', key)
  scriptTag.text = JSON.stringify(data)
  document.getElementsByTagName('head')[0].appendChild(scriptTag)
}

// 删除指定的script
export const deleteScript = key => {
  var scripts = document.getElementsByTagName('script')
  for (var i = 0; i < scripts.length; i++) {
    if (scripts[i].getAttribute('unique-key') === key) {
      scripts[i].parentNode.removeChild(scripts[i])
      return
    }
  }
}

// 根据当前集数，总集数确定组距，确定所在页码
export const getSpaceAndPage = (currEporder, totalEporder, fixed) => {
  const params = {
    pageNo: 1,
    pageSize: 10,
    ep: parseInt(currEporder),
    noSelections: true
  }
  // 为空的情况
  if (!totalEporder) {
    return {
      ...params,
      total: totalEporder,
      isEmpty: true
    }
  }
  // 只有一集的情况，可能是电影，也可以是电视剧
  if (totalEporder == 1) {
    return {
      ...params,
      total: totalEporder,
      noEporder: true
    }
  }
  // 十集以内
  if (1 < totalEporder && totalEporder <= 10) {
    return {
      ...params,
      total: totalEporder
    }
  }
  let pageSize = 10,
    pageNo = 1
  if (100 < totalEporder && totalEporder <= 300) {
    pageSize = 20
  } else if (300 < totalEporder && totalEporder < 1000) {
    pageSize = 30
  } else if (1000 <= totalEporder) {
    pageSize = 50
  }
  if (fixed) {
    pageSize = 50
  }
  pageNo = Math.ceil(currEporder / pageSize)
  return {
    ep: parseInt(currEporder),
    total: totalEporder, //总条数，
    pageSize, // 分页条数
    pageNo, //当前分页所在页码,
    selectionGroup: getSelectionsGroup(pageSize, totalEporder)
  }
}

// 根据组距，总集数，得到一个选集组
export const getSelectionsGroup = (space, totalEporder) => {
  if (totalEporder <= 10) {
    return []
  }
  const totalSize = Math.ceil(totalEporder / space),
    selectionGroup = []
  for (let i = 0; i < totalSize; i++) {
    let label = `${i * space + 1}~${(i + 1) * space}`
    if (i + 1 === totalSize) {
      label = `${i * space + 1}~${totalEporder}`
    }
    selectionGroup.push({
      value: i + 1,
      label
    })
  }
  return selectionGroup
}


export const fileSaver = (url,fileName) => {
  const link = document.createElement('a')
  link.href = url
  link.download = fileName
  document.body.append(link)
  link.click()
  link.remove()
}